<?php
namespace Tyrone\Lib;

use Medoo\Medoo;
use Swoole\Coroutine\Channel;

class DatabasePool
{
    private $pool;
    private $config;
    private $debug;

    public function __construct(array $config, $size = 10,$options=[])
    {
        $this->config = $config;
        $this->pool = new Channel($size);
        $this->pingEnabled = $options['ping'] ?? true;
        $this->debug = $options['debug'] ?? false;
        // 预先创建连接并放入池中
        $this->addConnection($size);
    }

    public function addConnection($num){
        for ($i = 0; $i < $num; $i++) {
            $this->put($this->createConnection());
        }
    }
    public static function createStaticConnectionBy($database,$host,$port,$username,$password){
        return self::createStaticConnection(compact('database','host','port','username','password'));
    }

    public static function createStaticConnection($config){
        return new SafeMedoo([
            'database_type'     => $config['type'] ?? 'mysql',
            'server'     => $config['host'],
            'port'     => $config['port'] ?? 3306,
            'database_name' => $config['database'],
            'username' => $config['username'],
            'password' => $config['password'],
            'charset'  => $config['charset'] ?? 'utf8mb4',
            // 注意：关闭持久连接，由连接池管理
            'option'   => [
                \PDO::ATTR_PERSISTENT => false,
                \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
            ],
            //'logging' => true,
            'trace_file' => './test.log',
            'trace_on' => 1,
        ],null);
    }

    /**
     * 创建一个新的 Medoo 连接
     */
    public function createConnection()
    {
        $medoo =  new SafeMedoo([
            'database_type'     => $this->config['type'] ?? 'mysql',
            'server'     => $this->config['host'],
            'port'     => $this->config['port'] ?? 3306,
            'database_name' => $this->config['database'],
            'username' => $this->config['username'],
            'password' => $this->config['password'],
            'charset'  => $this->config['charset'] ?? 'utf8mb4',
            // 注意：关闭持久连接，由连接池管理
            'option'   => [
                \PDO::ATTR_PERSISTENT => false,
                \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
            ],
            //'logging' => true,
            'trace_file' => './test.log',
            'trace_on' => 1,
        ],$this);
        if($this->debug){
            //return $medoo->debug();
        }
        return $medoo;
    }


    /**
     * 从连接池获取一个连接（协程安全）
     */
    public function get()
    {
        $connection = $this->pool->pop();

        if ($this->pingEnabled) {
            try {
                $connection->query("SELECT 1");
            } catch (\Throwable $throwable) {
                echo "Ping failed: " . $throwable->getMessage() . "\n";
                $connection = $this->createConnection();
            }
        }

        return $connection;
    }

    /**
     * 将连接归还给连接池
     */
    public function put($connection)
    {
        // 尝试归还连接，如果池已满则丢弃旧连接
        if ($this->pool->isFull()) {
            // 可选：记录日志或触发告警
            echo "Pool is full, connection discarded.\n";
            return false;
        }

        $this->pool->push($connection);
        return true;
    }

    /**
     * 关闭所有连接（用于 Worker 退出时）
     */
    public function close()
    {
        while (!$this->pool->isEmpty()) {
            // Medoo 没有显式 close 方法，PHP 会在对象销毁时关闭 PDO
            $this->pool->pop();
        }
    }
}